/***********************************************************
  RDD.h
  Moment Decision Diagram (MDD) Class
  SMART -- Symbolic Moment Analysis for Rapid Timing
  06-08-2008
  (c) Guoyong Shi;  SJTU
  09-11-2008
  Zhigang Hao; SJTU  
 ***********************************************************/


#ifndef RDD_H
#define RDD_H

#include <iostream>
#include <fstream>
#include <vector>

#include "ToGraph.h"
#include "RddStruct.h"

using namespace std;

class RDD
{

  public:

    RDD(ToGraph *tograph);
    ~RDD();

    inline int Get_Num_Edges() { return NumEdges;}
    inline int Get_Num_Nodes() { return NumNodes;} 

    inline double Get_Num_Terms() { return NumTerms;}

    void Create_RDD();
    void Create_RDD_r(C_NODE *ctree, BDD_Node *RDDelse);

    void Delete_RDD();

    inline C_NODE* Get_CTree()  { return Graph->Get_CTree();}

    void Print_Symbolic_Moments();
    void Print_RDD_r(BDD_Node *RDDroot);

    void Evaluate_Moments(int order);
    double  Evaluate_RDD_r(BDD_Node *RDDroot);
    double  Evaluate_L_Moment_r(BDD_Node *RDDroot);

    // Generate all moments up to the <order>.
    void Request_Moment_Order(int order);

    double *Get_Moment(int order);
    int Get_Moment_Length() { return RDD_Size; }

    void Dump_Moments(int order, ostream &output = cout, int cnt=0);
    void Dump_IndexToNode(ostream &output = cout);
    int Get_MaxOrder() { return MaxOrder; }
    ToGraph *Get_Graph() { return Graph; }


  private:

    int   NumNodes;   // number of BDD nodes
    int   NumEdges;   // number of BDD edges

    double  NumTerms;   // number of product terms represented
    // Because this number could be large, a <double> is used.

    ToGraph  *Graph;
    C_NODE   *CTree;     //the C-Tree root provided

    int   RDD_Size;  
    // size of RDD (equal to the length of moment vector

    BDD_Node  *RDD_Zero;     // the RDD zero node

    int   MaxOrder;  // saves the highest order of moments
    // Default to "2". Saved moments are Moment[0] ... Moment[MaxOrder-1].
    double  **Moment;  // for saving the moments

    // MomentIn and MomentOut are used to calculate higher order moments.
    // MomentIn points to the C-Tree nodes while MomentOut points to
    // the RDD nodes.
    C_NODE   **MomentIn;  // the list of moments input
    BDD_Node  **MomentOut;  // the list of moments output
};

#endif

